import logging

import yaml

logger = logging.getLogger(__name__)


def read_test_case(yaml_path):
    """
    将yaml测试用例类型分为三种测试用例
        1. 流程用例
        2. 单接口
        3. 数据驱动
    没改之前，一个yaml存入多个[]请求，按照数据驱动处理，现在新增parametrize标签，用于单独管理数据驱动
    同一个yaml存入多个[]请求，作为流程用例
    只存入一个[]请求，作为单接口
    只要请求中存在parametrize,均作为数据驱动处理
    :param yaml_path:
    :return:
    """
    with open(yaml_path, 'r', encoding='utf-8') as f:
        test_case_list = yaml.safe_load(f)
        if len(test_case_list) >= 2:
            # 流程用例：格式如下：[{},{},{}]
            # 转换为：[[{},{},{}]]
            # 注解parametrize,可以解包变为[{},{},{}],
            # 在执行方法处，进行for循环，将数据驱动变为流程用例
            logger.debug('流程用例')
            return [test_case_list]
        else:
            if "parametrize" in dict(*test_case_list).keys():
                # 目前数据驱动，仅允许在，单接口中出现，不允许出现在流程用例中
                # 数据驱动,格式如下[{...}]
                logger.debug('参数化用例')
                many_case = parametrize_case(*test_case_list)
                return many_case
            else:
                # 单接口，格式如下：[]
                # 直接返回，[{}]
                logger.debug('单接口')
                return [test_case_list]


def parametrize_case(test_case_yaml: dict):
    """
    将数据驱动，转为多个请求yaml
        前提条件：存在: $ddt{username}
          parametrize:
    - ['loginName', 'pageSize', 'pageNum', 'orderByColumn', 'status']
    - ['test','10','1','createTime','0']
    :param test_case_yaml: yaml数据，dict类型
    :return: [正例]、[反例]、[反例]
    """
    parametrize_data_list = test_case_yaml['parametrize']
    # 数据驱动的列，或者使用数据驱动的字段，$ddt{loginName}
    header_name = parametrize_data_list[0]
    # 数据驱动的字段长度和数据长度，必须一致
    len_flag = True
    for data in parametrize_data_list:
        if len(header_name) != len(data):
            len_flag = False
            print('parametrize参数化字段长度不一致')
            break

    case_info = yaml.dump(test_case_yaml)
    new_data_case = []
    if len_flag:
        # 参数化，数据行
        for y in range(1, len(parametrize_data_list)):
            # 复制一份数据值
            str_case_info: str = case_info
            for x in range(len(header_name)):
                # 替换 参数变量
                str_case_info = str_case_info.replace('$ddt{' + header_name[x] + '}',
                                                      str(parametrize_data_list[y][x]))
            dict_case_info: dict = yaml.safe_load(str_case_info)
            dict_case_info.pop('parametrize')
            new_data_case.append([dict_case_info])

    return new_data_case
